<?php
/**
 * ExtCRUDController class file
 *
 * @author TrueSoftware B.V. (The Netherlands)
 * @link http://www.ext4yii.com
 * @copyright Copyright 2007-2010 TrueSoftwareB.V. all rights reserved.
 * @license http://www.ext4yii.com/license/
 *          EVALUATION VERSION - NOT FOR COMMERCIAL USE OR DISTRIBUTION.
 * @version 0.7.2
 */

/**
 * This class in an abstract class for handling CRUD operations using a writable Store. 
 */
abstract class ExtCRUDController extends ExtController
{

    protected $recordRoot = 'rows';

    /**
     * @view
     * Abstract method that must be implemented in order be able to read CRUD values.
     * If you need to read a specific value you shoild use the $_POST collention
     * in combination with sending BaseParameters from either Store of BasicForm
     * components.
     */
    protected abstract function handleReadAction();

    /**
     * @view
     * Abstract method that must be implemented in order to be able to update CRUD records.
     * @param array $rows updated records sent from a store.
     */
    protected abstract function handleUpdateAction($rows);

    /**
     * @view
     * Abstract method that must be implemented in order to be able to create CRUD records.
     * @param array $rows new records sent from a store.
     */
    protected abstract function handleCreateAction($rows);

    /**
     * @view
     * Abstract method that must be implemented in order to be able to delete CRUD records.
     * @param array $rows deleted records sent from a store.
     */
    protected abstract function handleDestroyAction($rows);

    protected function getReaderIdProperty($storeid)
    {
        return Yii::app()->session[$storeid . '_reader_idproperty'];
    }

    protected function initialize()
    {

    }

    protected function crudError($message)
    {
        header('HTTP/1.1 500 EXT4YII_CRUD_ERROR');
        echo $message;
    }

    private function checkRows()
    {
        if (!isset($_POST[$this->recordRoot]))
        {
            $this->crudError(
                    'CRUD action does not have a valid record root element.<br/><br/>' .
                    'Please check the Store->reader->root property or overrride the $recordRoot property in your controller.');
            return false;
        }
        return true;
    }

    private function getUpdateRows()
    {
        return CJSON::decode($_POST[$this->recordRoot], true);
    }

    private function callHandler($handler)
    {
        $this->initialize();
        if ($this->checkRows())
        {
            try
            {
                $rows = call_user_func(array($this, $handler), $this->getUpdateRows());
                if (is_string($rows))
                {
                    echo $rows;
                }
                else if (is_array($rows))
                {
                    if (!isset($rows['success']) || (isset($rows['success']) && !is_bool($rows['success'])))
                    {
                        $this->crudError($handler . ' returned an array but the without a \'success\' => true/false attribute!<br/><br/>' . print_r($rows, true));
                    }
                    else
                    {
                        echo CJSON::encode($rows);
                    }
                }
                else if (is_bool($rows))
                {
                    echo CJSON::encode(array('success' => $rows));
                }
                else if (is_null($rows))
                {
                    echo CJSON::encode(array('success' => false));
                }
                else
                {
                    echo CJSON::encode(array('success' => true, 'value' => $rows));
                }
            } catch (Exception $ex)
            {
                $this->crudError(sprintf("<pre>File:%s<br/>Line:%s<br/>%s<br/>%s</pre>", $ex->getFile(), $ex->getLine(), $ex->getMessage(), $ex->getTraceAsString()));
            }
        }
    }

    public function action_create()
    {
        $this->callHandler('handleCreateAction');
    }

    public function action_read()
    {
        $this->initialize();
        $rows = $this->handleReadAction();
        if (is_array($rows))
            echo $this->ExportToJSONDataSource($rows);
        else
            echo $rows;
    }

    public function action_update()
    {
        $this->callHandler('handleUpdateAction');
    }

    public function action_destroy()
    {
        $this->callHandler('handleDestroyAction');
    }

}

?>
